MODULE NEWTON_HELPER
!
! Verwendungszweck:
!
!      Enthaelt den 'anwendungorientierten' Teil der fuer das Newton Verfahren verwendeten Routinen
!
!          AUXILARIES    : Materialfunktionen, Hilfsvariable & Normierung
!          MAKE_G        : Aufstellen von G
!          MAKE_DG       : Aufstellen von DG
!
!-----------------------------------------------------------------------

      implicit none

      private
      public :: AUXILARIES, MAKE_G, MAKE_DG

CONTAINS





SUBROUTINE AUXILARIES
!
! Verwendungszweck:
!
!      Berechnen von Materialfunktionen, Hilfsvariable & Normierung.
!
! 'auxilaries' wird im code 2 mal aufgerufen: in 'getready' und in 'newton'
!
!-----------------------------------------------------------------------
! Interne Variable:
!
!   t1, t2      : Zeitvariablen fuers profiling
!
!-----------------------------------------------------------------------

      use global,   only : zz, t_mater, t_edd
      use primvar,  only : ng, X, XZ, XA
      use config,   only : rkind
      use physco,   only : z1

      use matvar,   only : MATFCT
      use eddvar,   only : EDDFCT
      use geomvar,  only : GEOMET
      use zvar,     only : ZINT
      use viscvar,  only : VISCO
      use gridvar,  only : GRID
      use advecvar, only : ADVEC

      implicit none

      external CALC_TAU, CALC_XNORM

      real(kind=rkind) :: t1, t2


!-----------------------------------------------------------------------
!  Neuer zeitlich zentrierter Variablensatz
!-----------------------------------------------------------------------

      XZ(1:ng,:) = zz * X(1:ng,:) + (z1-zz) * XA(1:ng,:)


!-----------------------------------------------------------------------
!  Materialfunktionen, Hilfsvariable & Normierung fuer die neuen X, XZ
!-----------------------------------------------------------------------

      call ZINT       !  Berechnung von H_p und rho0

      call cpu_time(t1)
      call MATFCT     !  Materialfunktionen fuer das neue X und XZ
      call cpu_time(t2); t_mater = t_mater + t2 - t1
      call EDDFCT     !  Eddington Faktoren fuer das neue Modell
!      call cpu_time(t1); t_edd = t_edd + t1 - t2     ! xxx  zum testen nach unten kopiert

      call GEOMET     !
      call VISCO      !  Diverse Hilfsvariable fuer
      call GRID       !  den neuen Variablensatz X, XZ
      call ADVEC      !

      call CALC_TAU   !  zeitliche Daempfung-Zeitskala des adaptiven Gitters
      call CALC_XNORM !  Normierungsfaktoren fuer das neue X
      call cpu_time(t1); t_edd = t_edd + t1 - t2  ! xxx  nur zum testen

!     ZINT       :  no dependencies
!     MATFCT     :  requires zint
!     EDDFCT     :  no dependencies
!     GEOMET     :  no dependencies
!     VISCO      :  requires geomet & matfct
!     GRID       :  requires geomet & matfct
!     ADVEC      :  requires geomet
!     CALC_TAU   :  no dependencies (as for now)
!     CALC_XNORM :  requires matfct


END SUBROUTINE AUXILARIES





SUBROUTINE MAKE_G
!-----------------------------------------------------------------------
!    Aufstellen von G
!-----------------------------------------------------------------------

      use primvar, only : ng, G, Gnorm
      use physco,  only : z0

      implicit none

      external G_GRID, G_CONT, G_ENE, G_MOT_R, G_MOT_PHI, G_RADENE, G_RADFLX


      G(1:ng,:)  = z0

      !Aufstellen von G
!$OMP PARALLEL SECTIONS
!$OMP SECTION
!~       call G_GRID
!$OMP SECTION
      call G_CONT
!$OMP SECTION
      call G_ENE
!$OMP SECTION
      call G_MOT_R
!$OMP SECTION
      call G_MOT_PHI
!$OMP SECTION
      call G_RADENE
!$OMP SECTION
      call G_RADFLX
!$OMP END PARALLEL SECTIONS

      !Normieren von G
      G(1:ng,:) = G(1:ng,:) / Gnorm(1:ng,:)

END SUBROUTINE MAKE_G





SUBROUTINE MAKE_DG
!-----------------------------------------------------------------------
!    Aufstellen von DG
!-----------------------------------------------------------------------
! Interne Variable:
!
!   GL, idx  : Schleifenindizes
!
!-----------------------------------------------------------------------

      use primvar, only : ng, DG, Gnorm
      use config,  only : np
      use physco,  only : z0

      implicit none

      integer :: idx, GL

      external DG_GRID, DG_CONT, DG_ENE, DG_MOT_R, DG_MOT_PHI, DG_RADENE, DG_RADFLX


      DG(1:ng,1:ng,:,:) = z0

      !Aufstellen von DG
!$OMP PARALLEL SECTIONS
!$OMP SECTION
!~       call DG_GRID
!$OMP SECTION
      call DG_CONT
!$OMP SECTION
      call DG_ENE
!$OMP SECTION
      call DG_MOT_R
!$OMP SECTION
      call DG_MOT_PHI
!$OMP SECTION
      call DG_RADENE
!$OMP SECTION
      call DG_RADFLX
!$OMP END PARALLEL SECTIONS

      !Normieren von DG
      forall( idx = 1:np, GL = 1:ng )
         DG(GL,1:ng,:,idx) = DG(GL,1:ng,:,idx) / Gnorm(GL,idx)
      end forall

END SUBROUTINE MAKE_DG


END MODULE NEWTON_HELPER
